<template>
    <div>
        <el-form label-width="110px" size="small">
            <el-row class="form-row">
                <el-col :span="12">
                    <el-form-item label="产品代码:">
                        <RiskEntryInput id="fundCode" name="产品代码" @set-entry-data="getEntryslist" :returnDatas="instruction.fundCode" />
                    </el-form-item>
                    <el-form-item label="资产单元编号:" v-show="SHOW_SECURITY">
                        <el-select v-model="instruction.assetCode" size="mini">
                            <el-option
                                v-for="i in computedAssetCodeSelectData"
                                :key="i.assetCode"
                                :label="i.assetCode + ' ' + i.assetName"
                                :value="i.assetCode"
                            >
                            </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="组合编码:">
                        <el-select name="组合编码" v-model="instruction.fundAccountCode" size="mini" @change="handleFundAccountCodeChange">
                            <el-option
                                v-for="i in computedFundAccountCodeSelectData"
                                :key="i.fundAccountCode"
                                :label="i.fundAccountCode + ' ' + i.fundAccountName"
                                :value="i.fundAccountCode"
                            >
                            </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="证券代码:">
                        <el-select
                            name="证券代码"
                            ref="searchSelect"
                            size="mini"
                            clearable
                            filterable
                            :filter-method="getstockCodeList"
                            :loading="selectLoading"
                            v-model="instruction.stockCode"
                            @change="handleStockCode"
                            @visible-change="handleStockVisibleChange"
                            @focus="selectFocus"
                            @clear="getstockCodeList('')"
                        >
                            <el-option
                                v-for="i in stockCodeSelectData"
                                :key="i.stockCode"
                                :label="i.stockCode + ' ' + i.stockName"
                                :value="i.stockCode"
                                :name="'stockCode' + i.stockCode"
                            >
                            </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="业务类型:">
                        <el-select name="业务类型" v-model="instruction.businessType" size="mini">
                            <el-option value="C" label="网下申购"></el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="委托方向:">
                        <el-select name="委托方向" v-model="instruction.orderDirection" size="mini" :class="['font-color-' + textColor]">
                            <el-option value="C" label="申购" :style="handleTextColor('C')"></el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="目标类型:" v-show="!SHOW_SECURITY">
                        <el-select name="目标类型" v-model="instruction.targetType" size="mini">
                            <el-option v-for="(value, key) in targetTypePojo" :key="key" :label="value" :value="key" :name="'targetType' + key">
                            </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="申购价格:">
                        <RiskInputNumber
                            id="orderPrice"
                            :input="instruction.orderPrice"
                            :inputAfter="'元'"
                            :colorStyle="textColor"
                            :maxlength="14"
                            :field="'orderPrice'"
                            :precision="2"
                            @getInputNumber="getInputNumber(arguments)"
                        >
                        </RiskInputNumber>
                    </el-form-item>
                    <el-form-item label="申购数量:">
                        <RiskInputNumber
                            id="orderAmount"
                            :disabled="instruction.targetType == '2'"
                            :readonly="!instruction.stockCode"
                            :input="instruction.orderAmount"
                            :inputAfter="
                                instruction.stockType == 'k'
                                    ? '张'
                                    : instruction.stockType == 'a' || instruction.stockType == 'd'
                                    ? '股'
                                    : instruction.stockType == '23' || instruction.stockType == '27' || instruction.stockType == '50'
                                    ? '份'
                                    : '股'
                            "
                            :maxlength="14"
                            :colorStyle="textColor"
                            :field="'orderAmount'"
                            :precision="0"
                            @getInputNumber="getInputNumber(arguments)"
                        >
                        </RiskInputNumber>
                    </el-form-item>
                    <el-form-item label="申购定金:">
                        <RiskInputNumber
                            :input="instruction.earnestBalance"
                            :inputAfter="'元'"
                            :colorStyle="textColor"
                            :precision="2"
                            :maxlength="15"
                            :field="'earnestBalance'"
                            @getInputNumber="getInputNumber(arguments)"
                        >
                        </RiskInputNumber>
                    </el-form-item>
                    <el-form-item label="申购金额:">
                        <RiskInputNumber
                            :disabled="instruction.targetType == '1'"
                            :input="instruction.orderBalance"
                            :inputAfter="'元'"
                            :colorStyle="textColor"
                            :precision="2"
                            :maxlength="14"
                            :field="'orderBalance'"
                            @getInputNumber="getInputNumber(arguments)"
                        >
                        </RiskInputNumber> </el-form-item
                    ><el-form-item label="交易对手:">
                        <el-select
                            name="交易对手"
                            v-model="instruction.opponentCode"
                            @change="getOpponentCode"
                            filterable
                            clearable
                            :filter-method="getOpponentCode"
                            :loading="selectLoading"
                            size="mini"
                            @visible-change="handleOpponentVisibleChange"
                        >
                            <el-option
                                v-for="i in opponentCodeSelectData"
                                :key="i.dictKey"
                                :label="i.dictKey + ' ' + i.dictKeyName"
                                :value="i.dictKey"
                                :name="'opponentCode' + i.dictKey"
                            >
                            </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="目标类型:" v-show="SHOW_SECURITY">
                        <el-select v-model="instruction.targetType" size="mini">
                            <el-option v-for="(value, key) in targetTypePojo" :key="key" :label="value" :value="key"> </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
    </div>
</template>

<script lang="ts">
import Invest from '@/common/dict/invest';
import DictionConstUtil, { objToArr, SGU_CACHE } from '@/utils/diction-const-util';
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import RiskInputNumber from '@/pages/risk-measure/components/risk-input-number.vue';
import { SelectOptionItemData } from '@/pages/risk-time/types/SelectOptionItemData';
import { getBusinessType } from '@/pages/risk-time/api';
import { Dictionary } from '@/pages/risk-time/types/Dictionary';
import RiskEntryInput from '@/common/components/risk-entry-input.vue';
import { getConfigItem, handleInverseAmount, handleLimitAmount, handleTextColor, highlightColor, uniqueFunc } from '@/utils/tools';

@Component({
    name: 'OfflineSubscribeForm',
    components: {
        RiskInputNumber,
        RiskEntryInput,
    },
})

// 网下申购指令表单
export default class OfflineSubscribeForm extends Vue {
    @Prop()
    detail: any;
    @Prop()
    stockInfoCache: any;
    @Prop()
    selectedStock: any;
    @Prop()
    notMesh: boolean;
    Invest: any = new Invest();
    handleTextColor = handleTextColor;
    selectLoading: boolean = false; // 下拉框远程搜索时的加载状态
    fundCodeSelectData: any[] = []; // 产品序号下拉框数据
    fundAccountCodeSelectData: any[] = []; // 组合编码下拉框数据
    opponentCodeSelectData: any[] = []; // 交易对手下拉框数据
    stockCodeSelectData: any[] = []; // 证券代码下拉框数据
    textColor: string = '';

    private instruction = {
        fundCode: '', // 产品代码
        fundAccountCode: '', // 组合编码
        reportCode: '', // 申报代码
        orderDirection: 'C', // 委托方向
        stockCode: '', // 证券代码
        stockNameSt: '',
        businessType: 'C',
        businessTypeName: 'C',
        orderPrice: '',
        orderAmount: '',
        orderBalance: '', // 指令金额
        fundNameSt: '',
        fundAccountName: '',
        opponentCode: '',
        earnestBalance: '',
        marketCode: '',
        assetCode: '',
        assetName: '',
        stockType: '',
        targetType: '1',
    };
    stockInfo: any = {};

    targetTypePojo: any = {}; // 目标类型枚举对象
    changeFlag: string = '1'; // 证券变动方向

    async mounted() {
        // 获取产品信息 (产品序号下拉框数据)
        this.fundCodeSelectData = await SGU_CACHE('FundInfo', '/fundInfo/list', []);
        // 获取组合编码下拉框数据
        let arr = await SGU_CACHE('FundAccount', '/fundInfo/accounts', []);
        arr.forEach(item => {
            this.fundAccountCodeSelectData[item.fundCode] = item.fundAccounts;
        });
        // 获取目标类型
        this.targetTypePojo = DictionConstUtil.targetType;
        // 获取证券代码下拉框数据
        this.getstockCodeList('');
        this.getOpponentCode('');
    }

    @Watch('instruction', { immediate: true, deep: true })
    setValues() {
        this.$emit('handleSettingValue', this.instruction, '9');
    }

    @Watch('stockInfoCache', { immediate: true, deep: true })
    onWatchStockInfo(newValue, oldValue) {
        if (this.stockInfoCache) {
            this.stockInfo = this.stockInfoCache;
            this.stockInfo.marketCode = this.stockInfo.marketNo;
            this.stockInfo.stockNameSt = this.stockInfo.stockName; // 返回的stockName实际是简称
            this.instruction.reportCode = this.stockInfo.reportCode;
            this.instruction.stockCode = this.stockInfo.stockCode;
            this.instruction.marketCode = this.stockInfo.marketNo;
            this.instruction.stockType = this.stockInfo.stockType;
        }
    }

    @Watch('selectedStock', { immediate: true, deep: true })
    onWatchStockCode(newValue, oldValue) {
        if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
            this.instruction.orderPrice = '';
            this.instruction.orderBalance = '';
            this.instruction.earnestBalance = '';
            this.instruction.orderAmount = '';
            this.instruction.reportCode = this.selectedStock.reportCode;
            this.instruction.orderPrice = this.selectedStock.lowerPrice;
            this.instruction.stockCode = this.selectedStock.stockCode;
            this.instruction.marketCode = this.selectedStock.marketNo;
            this.instruction.stockType = this.selectedStock.stockType;
        }
    }

    // // 监听 组合编码计算属性 (每当计算属性变动时 自动选中第一项)
    // @Watch('computedFundAccountCodeSelectData', { immediate: true, deep: true })
    // watchcomputedFundAccountCode(newData) {
    //     if (this.detail && this.detail.instruction) {
    //         this.instruction.fundAccountCode = this.detail.instruction.fundAccountCode;
    //     } else {
    //         if (newData && newData.length) {
    //             this.instruction.fundAccountCode = newData[0].fundAccountCode;
    //         }
    //     }
    // }
    SHOW_SECURITY = getConfigItem('SHOW_SECURITY');
    // 监听 资产单元计算属性 (每当计算属性变动时 自动选中第一项)
    @Watch('computedAssetCodeSelectData', { immediate: true, deep: true })
    watchcomputedAssetCode(newData) {
        if (!this.SHOW_SECURITY) {
            return;
        }
        let obj: any = {};
        if (newData && newData.length) {
            const d1 = newData.find(item => item.assetCode == this.instruction.assetCode);
            obj = d1 || newData[0];
        }
        this.instruction.assetCode = obj.assetCode;
        this.instruction.assetName = obj.assetName;
    }

    // 监听 组合编码计算属性 (每当计算属性变动时 自动选中第一项)
    @Watch('computedFundAccountCodeSelectData', { immediate: true, deep: true })
    watchcomputedFundAccountCode(newData) {
        let obj: any = {};
        if (newData && newData.length) {
            const d1 = newData.find(item => item.fundAccountCode == this.instruction.fundAccountCode);
            obj = d1 || newData[0];
        }
        this.instruction.assetCode = obj.assetCode;
        this.instruction.assetName = obj.assetName;
        this.instruction.fundAccountCode = obj.fundAccountCode;
        this.instruction.fundAccountName = obj.fundAccountName;
    }

    get computedAssetCodeSelectData(): any {
        return uniqueFunc(this.fundAccountCodeSelectData[this.instruction.fundCode], 'assetCode');
    }

    // 组合编码下拉框计算属性;
    get computedFundAccountCodeSelectData() {
        let data = this.fundAccountCodeSelectData[this.instruction.fundCode];
        let retData = [];
        if (data && this.SHOW_SECURITY) {
            const obj = data.filter(item => item.assetCode == this.instruction.assetCode);
            retData = obj || [];
        } else {
            retData = data;
        }
        return retData;
    }

    @Watch('detail', { immediate: true, deep: true })
    async setForm() {
        if (this.detail && Object.keys(this.detail).length) {
            let instruction = this.detail;
            // 获取组合编码下拉框数据
            let arr = await SGU_CACHE('FundAccount', '/fundInfo/accounts', []);
            arr.forEach(item => {
                this.fundAccountCodeSelectData[item.fundCode] = item.fundAccounts;
            });

            for (const key in instruction) {
                this.instruction[key] = instruction[key];
            }
            // 指令修改回显
            if (this.detail.instNo) {
                // 组合编码
                this.instruction.fundAccountCode = this.detail.groupCode;
                // 组合名称
                // this.instruction.fundAccountName = this.detail.groupName;
            }

            await this.getstockCodeList(this.detail.stockCode);
            this.stockInfo = this.stockCodeSelectData.find(item => item.stockCode === this.detail.stockCode);
            if (this.stockInfo) {
                this.instruction.reportCode = this.stockInfo?.reportCode;
                this.stockInfo.marketCode = this.stockInfo?.marketNo;
                this.instruction.marketCode = this.stockInfo?.marketNo;
                this.stockInfo.stockNameSt = this.stockInfo?.stockName; // 返回的stockName实际是简称
                // this.calEarnestBalance(this.instruction.orderBalance, this.stockInfo);

                this.$emit('getStockInfo', this.stockInfo, '9');
            }
        }
    }

    /**
     * 判断字段颜色
     */
    @Watch('instruction', { immediate: true, deep: true })
    handleFieldColor() {
        if (this.instruction.orderDirection === 'C') {
            this.textColor = highlightColor()[1];
        } else {
            this.textColor = highlightColor()[0];
        }
    }

    getInputNumber(args: any) {
        let value = args[0];
        let field = args[1];
        this.instruction[field] = value;
        if (['orderPrice', 'orderAmount'].includes(field)) {
            // setTimeout(() => {
            if (value !== '') {
                this.handlePriceOrAmountChange(field, value);
            }
            // }, 10);
        } else if (field === 'orderBalance') {
            this.handleOrderBalanceChange(value);
        }
    }

    getEntryslist(val: any) {
        this.instruction.fundCode = val;
        this.handleFundCodeChange(val);
    }

    // 获取交易对手方数据
    getOpponentCode(value: string) {
        this.$axios
            .post('/dict/opponent/select', {
                dictKey: value,
                dictKeyName: value,
            })
            .then((res: any) => {
                this.opponentCodeSelectData = res;
            });
    }

    handleOpponentVisibleChange(val: any) {
        if (!val) {
            this.getOpponentCode('');
        }
    }

    handleFundCodeChange(val: string): void {
        let fund = this.fundCodeSelectData.find(item => item.fundCode === val) || {};
        let fundAccount = (this.fundAccountCodeSelectData[this.instruction.fundCode] || [])[0] || {};
        this.instruction.fundNameSt = fund.fundNameSt;
        this.instruction.fundAccountCode = fundAccount.fundAccountCode;
        this.instruction.fundAccountName = fundAccount.fundAccountName;
        this.instruction.assetCode = fundAccount.assetCode;
        this.instruction.assetName = fundAccount.assetName;
    }

    handleFundAccountCodeChange(value: string) {
        let fundAccount = (this.fundAccountCodeSelectData[this.instruction.fundCode] || []).find(item => item.fundAccountCode === value) || {};
        this.instruction.fundAccountName = fundAccount.fundAccountName;
        this.instruction.assetCode = fundAccount.assetCode;
        this.instruction.assetName = fundAccount.assetName;
    }

    handleStockCode(stockCode: string): void {
        this.instruction.orderPrice = '';
        this.instruction.orderBalance = '';
        this.instruction.earnestBalance = '';
        this.instruction.orderAmount = '';
        if (stockCode) {
            this.stockInfo = this.stockCodeSelectData.find(item => item.stockCode === stockCode);
            this.stockInfo.stockNameSt = this.stockInfo?.stockName;
            this.stockInfo.marketCode = this.stockInfo?.marketNo;
            this.instruction.reportCode = this.stockInfo?.reportCode;
            this.instruction.orderPrice = this.stockInfo?.lowerPrice;
            this.instruction.marketCode = this.stockInfo?.marketNo;
            this.instruction.stockType = this.stockInfo?.stockType;
        } else {
            this.stockInfo = {};
        }
        this.$emit('getStockInfo', this.stockInfo, '9');
    }

    handlePriceOrAmountChange(field: string, value: any) {
        if (this.instruction.targetType == '1') {
            let orderBalance = (Number(this.instruction.orderPrice || '0') * Number(this.instruction.orderAmount || '0')).toString();

            if (this.convertNum(orderBalance) === false || Number(orderBalance) > 99999999999999.99) {
                this.yh_message_error('申购金额不能大于99999999999999.99!');
                return;
            }
            this.instruction.orderBalance = orderBalance.toString();

            // this.calEarnestBalance(this.instruction.orderBalance, this.stockInfo);
            if (this.selectedStock && JSON.stringify(this.selectedStock) != '{}') {
                this.calEarnestBalance(this.instruction.orderBalance, this.selectedStock);
            } else if (JSON.stringify(this.stockInfo) != '{}') {
                this.calEarnestBalance(this.instruction.orderBalance, this.stockInfo);
            }
        } else {
            let orderAmount: any;
            if (this.instruction.orderBalance) {
                if (this.instruction.orderPrice) {
                    orderAmount = Number(this.instruction.orderBalance) / Number(this.instruction.orderPrice);
                } else {
                    orderAmount = '';
                }
            } else {
                orderAmount = '';
            }
            this.instruction.orderAmount = orderAmount;
        }
        if (field === 'orderAmount') {
            if (value.toString()) {
                if (value.toString() == '0') {
                    this.yh_message_warn('申购数量必须大于0！');
                }
                // 限定指令数量
                let limit = handleLimitAmount(this.changeFlag, this.stockInfo, value);
                if (!limit) {
                    setTimeout(() => {
                        this.instruction.orderAmount = '';
                    }, 200);
                }
                // handleLimitAmount(this.textColor, this.stockInfo, value);
            }
        }
    }

    convertNum(num) {
        // 参数必须为 字符串
        // 科学计数法字符 转换 为数字字符， 突破正数21位和负数7位的Number自动转换
        // 兼容 小数点左边有多位数的情况，即 a×10^b（aEb），a非标准范围（1≤|a|<10）下的情况。如 3453.54E-6 or 3453.54E6
        var resValue = '';
        var power;
        var result = null;
        var dotIndex = 0;
        var resArr = [];
        var sym = '';
        var numStr = num.toString();
        if (numStr[0] == '-') {
            // 如果为负数，转成正数处理，先去掉‘-’号，并保存‘-’.
            numStr = numStr.substr(1);
            sym = '-';
        }
        console.log(numStr);
        if (numStr.indexOf('E') != -1 || numStr.indexOf('e') != -1) {
            var regExp = new RegExp('^(((\\d+.?\\d+)|(\\d+))[Ee]{1}((-(\\d+))|(\\d+)))$', 'ig');
            result = regExp.exec(numStr);
            console.log(result);
            if (result != null) {
                resValue = result[2];
                power = result[5];
                result = null;
            }
            if (!resValue && !power) {
                return false;
            }
            dotIndex = resValue.indexOf('.');
            resValue = resValue.replace('.', '');
            resArr = resValue.split('');
            if (Number(power) >= 0) {
                var subres = resValue.substr(dotIndex);
                power = Number(power);
                // 幂数大于小数点后面的数字位数时，后面加0
                for (var i = 0; i < power - subres.length; i++) {
                    resArr.push('0');
                }
                if (power - subres.length < 0) {
                    resArr.splice(dotIndex + power, 0, '.');
                }
            } else {
                power = power.replace('-', '');
                power = Number(power);
                // 幂数大于等于 小数点的index位置, 前面加0
                for (let i = 0; i <= power - dotIndex; i++) {
                    resArr.unshift('0');
                }
                var n = power - dotIndex >= 0 ? 1 : -(power - dotIndex);
                resArr.splice(n, 0, '.');
            }
        }
        resValue = resArr.join('');
        console.log(sym + resValue);
        return sym + resValue;
    }

    handleOrderBalanceChange(val: any) {
        if (val === '' || val === undefined) {
            return;
        }
        if (!this.instruction.orderPrice) {
            this.instruction.orderAmount = '';
            return;
        }
        this.instruction.orderAmount = parseInt(
            (Number(this.instruction.orderBalance || '0') / Number(this.instruction.orderPrice || '0')).toString()
        ).toString();
        // 反算指令数量处理
        this.instruction.orderAmount = handleInverseAmount(this.changeFlag, this.stockInfo, this.instruction.orderAmount);
        if (this.selectedStock && JSON.stringify(this.selectedStock) != '{}') {
            this.calEarnestBalance(this.instruction.orderBalance, this.selectedStock);
        } else if (JSON.stringify(this.stockInfo) != '{}') {
            this.calEarnestBalance(this.instruction.orderBalance, this.stockInfo);
        }
        // this.calEarnestBalance(this.instruction.orderBalance, this.stockInfo);
    }

    selectFocus(e) {
        let value = e.target.value;
        if (!value) {
            this.getstockCodeList('');
        }
        // setTimeout(() => {
        //     let input = (this.$refs.searchSelect as any).$children[0].$refs.input;
        //     input.value = value;
        // });
    }

    // 防抖
    debounce(fn, delay) {
        let timer = null;
        return function () {
            if (timer !== null) {
                clearTimeout(timer);
            }
            timer = setTimeout(() => {
                // 对要调用的函数的this进行绑定，二选一
                // 第一种方式
                // fn.apply(this,arguments)
                // arguments 可以用来传递值
                // 第二种方式  还可以使用  fn.call(this)  来绑定this
                fn.call(this);
            }, delay);
        };
    }

    handleStockVisibleChange(val) {
        if (!val) {
            // this.getstockCodeList('');
            // let input = (this.$refs.searchSelect as any).$children[0].$refs.input;
            // input.blur();
        }
    }

    // 获取证券代码下拉框数据
    async getstockCodeList(val: string | undefined) {
        this.selectLoading = true;
        await this.$axios
            .post('/position/stock/offlineSubs', {
                paging: {
                    currentPage: 1,
                    pageSize: 20,
                },
                stockNameOrCode: val,
            })
            .then((res: any) => {
                this.stockCodeSelectData = res.list || [];
                this.selectLoading = false;
            });
    }

    // 申购定金 = 申购金额 * 定金比例 + 定金金额
    calEarnestBalance(orderBalance, stockInfo) {
        this.instruction.earnestBalance = (
            Number(orderBalance || '0') * Number(stockInfo.earnestRatio || '0') +
            Number(stockInfo.earnestBalance || '0')
        ).toString();
    }
}
</script>
<style lang="scss" scoped>
@import '@/pages/risk-measure/style/measure';

.form-row {
    margin-top: 3px;
    .el-form-item--small {
        margin: 0;
        & /deep/ .el-form-item__label {
            color: #575757;
        }
        & /deep/ .el-input__inner {
            height: 28px;
            line-height: 28px;
        }
        .font-color-red {
            /deep/ input {
                color: red !important;
            }
            /deep/ .el-input-group__append {
                color: red !important;
            }
        }
        .font-color-green {
            /deep/ input {
                color: green !important;
            }
            /deep/ .el-input-group__append {
                color: green !important;
            }
        }
    }
}
</style>
